<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" />

    

    

    <title>springcloud服务网关gateway搭建 | 郑礼德技术栈</title>
    <meta name="author" content="郑礼德" />
    <meta name="keywords" content="" />
    <meta name="description" content="对比之前用的zuul 网关，gateway 不仅可以对api 服务进行路由，还提供了一些如熔断，限流，重试等过滤性的功能，所以用的人更多    gateway简介spring cloud gateway 是spring官方基于spring 5.0 springboot2.0 开发的网关springcloud gateway 具有以下特性: 1.基于Spring Framework 5, Project Reactor 和 Spring Boot 2.0 进行构建；2.继承Hys..." />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />

    
    <link rel="alternate" href="/homepage/atom.xml" title="郑礼德技术栈" type="application/atom+xml">
    
    
    <link rel="icon" href="/homepage/images/favicon.ico">
    

    <style type="text/css">
    @font-face {
        font-family: 'icomoon';
        src: url("/homepage/fonts/icomoon.eot?q628ml");
        src: url("/homepage/fonts/icomoon.eot?q628ml#iefix") format('embedded-opentype'),
             url("/homepage/fonts/icomoon.ttf?q628ml") format('truetype'),
             url("/homepage/fonts/icomoon.woff?q628ml") format('woff'),
             url("/homepage/fonts/icomoon.svg?q628ml#icomoon") format('svg');
        font-weight: normal;
        font-style: normal;
    }
    </style>
    
<link rel="stylesheet" href="/homepage/css/style.css">


    <!--[if lt IE 9]>
    <style type="text/css">
    .nav-inner {top:0;}
    .author-meta {position:static;top:0;}
    .search-form {height:36px;}
    </style>
    <script type="text/javascript" src="https://unpkg.com/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
    <![endif]-->
<meta name="generator" content="Hexo 4.2.0"></head>
<body>

    <main class="app">
        <header id="header" class="header clearfix">
    <div id="nav" class="nav">
    <div class="nav-mobile">
        <button id="open-panel" class="open-panel nav-mobile-item"><i class="icon-documents"></i></button>
        <h1 class="nav-mobile-title nav-mobile-item">郑礼德技术栈</h1>
        <button id="open-menus" class="open-panel nav-mobile-item"><i class="icon-library"></i></button>
    </div>

    <nav id="nav-inner" class="nav-inner">
        
            <a class="nav-item" href="/homepage/">
                <span class="nav-text">首页</span>
            </a>
        
            <a class="nav-item" href="/homepage/categories/front-end">
                <span class="nav-text">前端</span>
            </a>
        
            <a class="nav-item" href="/homepage/categories/back-end">
                <span class="nav-text">后端</span>
            </a>
        
            <a class="nav-item" href="/homepage/categories/linux">
                <span class="nav-text">linux部署</span>
            </a>
        
            <a class="nav-item" href="/homepage/tags">
                <span class="nav-text">标签</span>
            </a>
        
            <a class="nav-item" href="/homepage/archives">
                <span class="nav-text">归档</span>
            </a>
        
            <a class="nav-item" href="/homepage/about">
                <span class="nav-text">关于</span>
            </a>
        
    </nav>
</div>

    <aside id="aside" class="aside">
    <div id="aside-mask" class="aside-mask"></div>
    <div id="aside-inner" class="aside-inner">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit"><i class="icon-search-stroke"></i></button><input type="hidden" name="sitesearch" value="http://zhenglide.gitee.io/homepage"></form>

        
        
        
        

        
        <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#gateway简介"><span class="toc-number">1.</span> <span class="toc-text">gateway简介</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#概念"><span class="toc-number">1.1.</span> <span class="toc-text">概念</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#搭建gateway"><span class="toc-number">2.</span> <span class="toc-text">搭建gateway</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#引入pom文件"><span class="toc-number">2.1.</span> <span class="toc-text">引入pom文件</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#配置路由的方式"><span class="toc-number">2.2.</span> <span class="toc-text">配置路由的方式</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#使用yml-进行配置"><span class="toc-number">2.2.1.</span> <span class="toc-text">使用yml 进行配置</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#以javabean的形式配置"><span class="toc-number">2.3.</span> <span class="toc-text">以javabean的形式配置</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#路由断言predicates"><span class="toc-number">3.</span> <span class="toc-text">路由断言predicates</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#After路由断言"><span class="toc-number">3.1.</span> <span class="toc-text">After路由断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Before路由断言"><span class="toc-number">3.2.</span> <span class="toc-text">Before路由断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Between路由断言"><span class="toc-number">3.3.</span> <span class="toc-text">Between路由断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Cookie路由断言"><span class="toc-number">3.4.</span> <span class="toc-text">Cookie路由断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Header路由断言"><span class="toc-number">3.5.</span> <span class="toc-text">Header路由断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Host路由断言"><span class="toc-number">3.6.</span> <span class="toc-text">Host路由断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#method-路由断言"><span class="toc-number">3.7.</span> <span class="toc-text">method 路由断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Path路由断言"><span class="toc-number">3.8.</span> <span class="toc-text">Path路由断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#query路由断言"><span class="toc-number">3.9.</span> <span class="toc-text">query路由断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#RomoteAddr路由断言"><span class="toc-number">3.10.</span> <span class="toc-text">RomoteAddr路由断言</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Weight-路由断言"><span class="toc-number">3.11.</span> <span class="toc-text">Weight 路由断言</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#路由filter-的使用"><span class="toc-number">4.</span> <span class="toc-text">路由filter 的使用</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#AddRequestParameter-过滤器"><span class="toc-number">4.1.</span> <span class="toc-text">AddRequestParameter 过滤器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#StripPrefix-过滤器"><span class="toc-number">4.2.</span> <span class="toc-text">StripPrefix 过滤器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#PrefixPath过滤器"><span class="toc-number">4.3.</span> <span class="toc-text">PrefixPath过滤器</span></a></li></ol></li></ol>
        
    </div>
</aside>

</header>

        <div id="content" class="content">
            <div id="wrapper" class="wrapper" style="max-width: 800px">
                <article class="article" itemscope itemprop="blogPost">
    
    <header class="article-header">
        
        <h1 itemprop="name">
            springcloud服务网关gateway搭建
        </h1>
        
        <div class="article-meta clearfix">
            <a class="article-date" href="http://zhenglide.gitee.io/homepage/2020/04/01/springcloud%E6%9C%8D%E5%8A%A1%E7%BD%91%E5%85%B3gateway%E6%90%AD%E5%BB%BA/index.html">
    
    <i class="icon-calendar"></i>
    
    <time datetime="2020-03-31T17:00:06.000Z" itemprop="datePublished">2020-04-01</time>
</a>

            
<div class="article-tag-list">
    <i class="icon-tag"></i>
    <a class="article-tag-link" href="/homepage/tags/springcloud/" rel="tag">springcloud</a>
</div>


        </div>
    </header>
    
    <section class="article-body markdown-body">
        
        <p>对比之前用的zuul 网关，gateway 不仅可以对api 服务进行路由，还提供了一些如熔断，限流，重试等过滤性的功能，所以用的人更多</p>
<a id="more"></a>    

<h2 id="gateway简介"><a href="#gateway简介" class="headerlink" title="gateway简介"></a>gateway简介</h2><p>spring cloud gateway 是spring官方基于spring 5.0 springboot2.0 开发的网关</p>
<p>springcloud gateway 具有以下特性:</p>
<p> 1.基于Spring Framework 5, Project Reactor 和 Spring Boot 2.0 进行构建；</p>
<p>2.继承Hystrix 断路器</p>
<p>3.具有网关的高级功能：动态路由，限流，路径重写</p>
<h3 id="概念"><a href="#概念" class="headerlink" title="概念"></a>概念</h3><p><strong>（</strong>1<strong>）</strong>Filter<strong>（过滤器）</strong>：</p>
<p>和Zuul的过滤器在概念上类似，可以使用它拦截和修改请求，并且对上游的响应，进行二次处理。过滤器为org.springframework.cloud.gateway.filter.GatewayFilter类的实例。</p>
<p>（2）<strong>Route</strong>（路由）：</p>
<p>网关配置的基本组成模块，和Zuul的路由配置模块类似。一个<strong>Route模块</strong>由一个 ID，一个目标 URI，一组断言和一组过滤器定义。如果断言为真，则路由匹配，目标URI会被访问。</p>
<p><strong>（</strong>3<strong>）</strong>Predicate<strong>（断言）</strong>：</p>
<p>这是一个 Java 8 的 Predicate，可以使用它来匹配来自 HTTP 请求的任何内容，例如 headers 或参数。<strong>断言的</strong>输入类型是一个 ServerWebExchange</p>
<h2 id="搭建gateway"><a href="#搭建gateway" class="headerlink" title="搭建gateway"></a>搭建gateway</h2><h3 id="引入pom文件"><a href="#引入pom文件" class="headerlink" title="引入pom文件"></a>引入pom文件</h3><pre><code class="yaml">&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter-gateway&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
<h3 id="配置路由的方式"><a href="#配置路由的方式" class="headerlink" title="配置路由的方式"></a>配置路由的方式</h3><h4 id="使用yml-进行配置"><a href="#使用yml-进行配置" class="headerlink" title="使用yml 进行配置"></a>使用yml 进行配置</h4><p>在application.yml中进行配置：</p>
<pre><code class="yaml">server:
  port: 9201
service-url:
  user-service: http://localhost:8201
spring:
  cloud:
    gateway:
      routes:
      - id: path_route #路由的ID
        uri: ${service-url.user-service}/user/{id} #匹配后路由地址
        predicates: # 断言，路径相匹配的进行路由
        - Path=/user/{id}</code></pre>
<h3 id="以javabean的形式配置"><a href="#以javabean的形式配置" class="headerlink" title="以javabean的形式配置"></a>以javabean的形式配置</h3><pre><code class="java">package com.zhenglide.cloud.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(&quot;path_route2&quot;, r -&gt; r.path(&quot;/user/getByUsername&quot;)
                        .uri(&quot;http://localhost:8201/user/getByUsername&quot;))
                .build();
    }
}
</code></pre>
<h2 id="路由断言predicates"><a href="#路由断言predicates" class="headerlink" title="路由断言predicates"></a>路由断言predicates</h2><h3 id="After路由断言"><a href="#After路由断言" class="headerlink" title="After路由断言"></a>After路由断言</h3><pre><code class="yaml">spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: ${service-url.user-service}
        predicates:
        - After=2020-04-05T16:30:00+08:00[Asia/Shanghai]</code></pre>
<h3 id="Before路由断言"><a href="#Before路由断言" class="headerlink" title="Before路由断言"></a>Before路由断言</h3><pre><code class="yaml">spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: ${service-url.user-service}
        predicates:
        - Before=2020-04-05T22:30:00+08:00[Asia/Shanghai]</code></pre>
<h3 id="Between路由断言"><a href="#Between路由断言" class="headerlink" title="Between路由断言"></a>Between路由断言</h3><pre><code class="yaml">spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: ${service-url.user-service}
        predicates:
        - Between=2019-09-24T16:30:00+08:00[Asia/Shanghai], 2019-09-25T16:30:00+08:00[Asia/Shanghai]</code></pre>
<h3 id="Cookie路由断言"><a href="#Cookie路由断言" class="headerlink" title="Cookie路由断言"></a>Cookie路由断言</h3><pre><code class="yaml">spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: ${service-url.user-service}
        predicates:
        - Cookie=username,zhenglide</code></pre>
<p>使用idea httpclient 工具请求加上cookie</p>
<img src="/homepage/2020/04/01/springcloud%E6%9C%8D%E5%8A%A1%E7%BD%91%E5%85%B3gateway%E6%90%AD%E5%BB%BA/cookie%E8%AF%B7%E6%B1%82.png" class="">

<h3 id="Header路由断言"><a href="#Header路由断言" class="headerlink" title="Header路由断言"></a>Header路由断言</h3><p>指定请求头的请求会匹配到该路由</p>
<pre><code class="yaml">spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: ${service-url.user-service}
        predicates:
        - Header=X-Request-Id, \d+</code></pre>
<p>使用idea httpclient 工具请求加上请求头</p>
<img src="/homepage/2020/04/01/springcloud%E6%9C%8D%E5%8A%A1%E7%BD%91%E5%85%B3gateway%E6%90%AD%E5%BB%BA/header%E8%AF%B7%E6%B1%82.png" class="">

<h3 id="Host路由断言"><a href="#Host路由断言" class="headerlink" title="Host路由断言"></a>Host路由断言</h3><p>指定主机域名访问</p>
<pre><code class="yaml">spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: ${service-url.user-service}
        predicates:
          - Host=**.zengbb.cn</code></pre>
<h3 id="method-路由断言"><a href="#method-路由断言" class="headerlink" title="method 路由断言"></a>method 路由断言</h3><p>指定特定方法访问</p>
<pre><code class="yaml">spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: ${service-url.user-service}
        predicates:
        - Method=GET</code></pre>
<h3 id="Path路由断言"><a href="#Path路由断言" class="headerlink" title="Path路由断言"></a>Path路由断言</h3><p>指定路径断言</p>
<pre><code class="yaml">spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: ${service-url.user-service}/user/{id}
        predicates:
        - Path=/user/{id}</code></pre>
<h3 id="query路由断言"><a href="#query路由断言" class="headerlink" title="query路由断言"></a>query路由断言</h3><p>指定参数断言</p>
<pre><code class="yaml">spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: ${service-url.user-service}/user/getByUsername
        predicates:
        - Query=username</code></pre>
<h3 id="RomoteAddr路由断言"><a href="#RomoteAddr路由断言" class="headerlink" title="RomoteAddr路由断言"></a>RomoteAddr路由断言</h3><p>从指定远程地址发起的请求可以匹配该路由。</p>
<pre><code class="yaml">spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: ${service-url.user-service}
        predicates:
        - RemoteAddr=192.168.1.1/24
</code></pre>
<h3 id="Weight-路由断言"><a href="#Weight-路由断言" class="headerlink" title="Weight 路由断言"></a>Weight 路由断言</h3><p>使用权重匹配路由</p>
<pre><code class="yaml">spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: http://localhost:8201
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: http://localhost:8202
        predicates:
        - Weight=group1, 2
</code></pre>
<h2 id="路由filter-的使用"><a href="#路由filter-的使用" class="headerlink" title="路由filter 的使用"></a>路由filter 的使用</h2><p>路由过滤器可以对请求和响应进行修改，gateway提供了很多内置的过滤器</p>
<h3 id="AddRequestParameter-过滤器"><a href="#AddRequestParameter-过滤器" class="headerlink" title="AddRequestParameter 过滤器"></a>AddRequestParameter 过滤器</h3><p>  可以对请求添加请求参数</p>
<h3 id="StripPrefix-过滤器"><a href="#StripPrefix-过滤器" class="headerlink" title="StripPrefix 过滤器"></a>StripPrefix 过滤器</h3><p>该过滤器可以对指定数量的前缀进行去除</p>
<h3 id="PrefixPath过滤器"><a href="#PrefixPath过滤器" class="headerlink" title="PrefixPath过滤器"></a>PrefixPath过滤器</h3><p>可以对原有路径进行增加操作</p>

        
    </section>
</article>



<a id="pagenext" href="/homepage/2020/03/31/springcloud%E6%B3%A8%E5%86%8C%E4%B8%AD%E5%BF%83eureka/" class="article-next" title="springcloud注册中心eureka"><i class="icon-arrow-right"></i></a>


<a id="pageprev" href="/homepage/2020/04/05/%E6%B5%85%E8%B0%88%E4%BD%BF%E7%94%A8%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%87%8F%E5%B0%91if-else/" class="article-prev" title="浅谈使用设计模式减少if-else"><i class="icon-arrow-left"></i></a>




            </div>
        </div>
        <footer class="footer">
    Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>, Theme by <a href="https://github.com/sanonz/hexo-theme-concise" target="_blank">Concise</a>

    
    <script>
        var _hmt = _hmt || [];
        (function () {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?b13bb4c2ef8300062aab9732bd22eae0";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
    </script>
    
</footer>

    </main>

    <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.9.0/jquery.min.js"></script>
    <script type="text/javascript">
    $(function() {
        var nodes = {
            nav: $('#nav'),
            aside: $('#aside'),
            asideInner: $('#aside-inner'),
            navInner: $('#nav-inner')
        };

        var doing = false;
        nodes.asideInner.on('webkitAnimationEnd mozAnimationEnd oAnimationEnd oanimationend animationend', function() {
            if (nodes.aside.hasClass('mobile-open')) {
                nodes.aside.removeClass('mobile-open');
            } else {
                nodes.aside.removeClass('mobile-close panel-show');
            }
            doing = false;
        });
        $('#open-panel, #aside-mask').on('click', function() {
            if (doing) {
                return;
            }

            if (nodes.aside.hasClass('panel-show')) {
                nodes.aside.addClass('mobile-close');
            } else {
                nodes.aside.addClass('mobile-open panel-show');
            }
        });
        $('#open-menus').on('click', function() {
            nodes.navInner.slideToggle();
        });

        if (window.innerWidth <= 960) {
            setTimeout(function() {
                nodes.navInner.slideUp();
            }, 3000);
        }
    });
    </script>
    
        
<script src="/homepage/js/scrollspy.min.js"></script>

        <script type="text/javascript">
        $(document.body).scrollspy({target: '#aside-inner'});

        $(window).on('resize', function() {
            var hw = $('#header').width();
            var ww = $('#wrapper').width();
            var space = ($(this).width() - hw - ww) / 2 / 2;

            var pageprev = $('#pageprev');
            var pagenext = $('#pagenext');
            var avg = (pageprev.width() + pagenext.width()) / 2

            if(space > avg) {
                var len = space - avg / 2;
                var styles = {position: 'fixed', top: '50%', marginTop: - (pageprev.width() + pagenext.width()) / 4}
                pageprev.css($.extend({left: hw + len}, styles));
                pagenext.css($.extend({right: len}, styles));
            } else {
                pageprev.removeAttr('style');
                pagenext.removeAttr('style');
            }
        }).trigger('resize');
        </script>
    

</body>
</html>
